﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DevExpress.XtraEditors;
using System.Drawing;
using DevExpress.Accessibility;
using System.Windows.Forms;
using DevExpress.LookAndFeel;
using DevExpress.Utils.Drawing;
using DevExpress.Utils;
using DevExpress.Skins.XtraForm;
using DevExpress.XtraEditors.Controls;
using DevExpress.Skins;
using System.ComponentModel;

namespace KNS.Invoice.UI
{
    public class KNSMessageBoxForm : XtraForm
    {
        // Fields
        private SimpleButton[] buttons;
        private BaseAccessible dxAccessible;
        private Rectangle iconRectangle;
        private XtraMessageBoxArgs message;
        private Rectangle messageRectangle;
        private const int Spacing = 12;
        private int maxLabelWidth = Screen.PrimaryScreen.WorkingArea.Width;

        // Methods
        public KNSMessageBoxForm()
        {
            base.KeyPreview = true;
            this.message = new XtraMessageBoxArgs();
        }

        private void CalcFinalSizes()
        {
            int num = 0;
            foreach (SimpleButton button in this.buttons)
            {
                if (num != 0)
                {
                    num += 12;
                }
                num += button.Width;
            }
            int y = this.messageRectangle.Bottom + 12;
            if ((this.Message.Icon != null) && ((this.iconRectangle.Bottom + 12) > y))
            {
                y = this.iconRectangle.Bottom + 12;
            }
            int width = this.MinimumSize.Width;
            if (width == 0)
            {
                width = SystemInformation.MinimumWindowSize.Width;
            }
            if (width < (this.messageRectangle.Right + 12))
            {
                width = this.messageRectangle.Right + 12;
            }
            if (width < ((num + 12) + 12))
            {
                width = (num + 12) + 12;
            }
            GraphicsInfo info = new GraphicsInfo();
            info.AddGraphics(null);
            try
            {
                using (StringFormat format = TextOptions.DefaultStringFormat.Clone() as StringFormat)
                {
                    format.FormatFlags |= StringFormatFlags.MeasureTrailingSpaces;
                    using (Font font = this.GetCaptionFont())
                    {
                        int num4 = (int)Math.Ceiling((double)info.Cache.CalcTextSize(this.Text, font, format, 0).Width);
                        int num5 = num4 + this.GetBordersSizes().Width;
                        int num6 = num5;
                        if (base.ControlBox)
                        {
                            num6 += this.GetCloseButtonWidth();
                        }
                        num6 += 2;
                        int num7 = (SystemInformation.WorkingArea.Width / 3) * 2;
                        int num8 = Math.Min(num7, num6);
                        if (width < num8)
                        {
                            width = num8;
                        }
                    }
                }
            }
            finally
            {
                info.ReleaseGraphics();
            }
            base.Width = width + this.GetBordersSizes().Width;
            base.Height = ((y + this.buttons[0].Height) + 12) + this.GetBordersSizes().Height;
            int x = width - num - 12;//(width - num) / 2;
            for (int i = 0; i < this.buttons.Length; i++)
            {
                this.buttons[i].Location = new Point(x, y);
                x += this.buttons[i].Width + 12;
            }
            if (this.Message.Icon == null)
            {
                this.messageRectangle.Offset((width - (this.messageRectangle.Right + 12)) / 2, 0);
            }
            if ((this.Message.Icon != null) && (this.messageRectangle.Height < this.iconRectangle.Height))
            {
                this.messageRectangle.Offset(0, (this.iconRectangle.Height - this.messageRectangle.Height) / 2);
            }
        }

        private void CalcIconBounds()
        {
            if (this.Message.Icon != null)
            {
                this.iconRectangle = new Rectangle(12, 12, this.Message.Icon.Width, this.Message.Icon.Height);
            }
            else
            {
                this.iconRectangle = new Rectangle(12, 12, 0, 0);
            }
        }

        private void CalcMessageBounds()
        {
            int y = 12;
            int x = (this.Message.Icon == null) ? 12 : ((this.iconRectangle.Left + this.iconRectangle.Width) + 12);
            int width = this.MaximumSize.Width;
            if (width <= 0)
            {
                width = SystemInformation.WorkingArea.Width;
            }
            int num6 = ((width - this.GetBordersSizes().Width) - 12) - x;
            if (num6 < 10)
            {
                num6 = 10;
            }
            GraphicsInfo info = new GraphicsInfo();
            info.AddGraphics(null);
            SizeF ef = this.GetPaintAppearance().CalcTextSize(info.Graphics, this.Message.Text, num6);
            info.ReleaseGraphics();
            int num3 = (int)Math.Ceiling((double)ef.Width);
            int height = this.MaximumSize.Height;
            if (height <= 0)
            {
                height = SystemInformation.WorkingArea.Height;
            }
            int num8 = ((((height - 12) - this.buttons[0].Height) - 12) - y) - this.GetBordersSizes().Height;
            if (num8 < 10)
            {
                num8 = 10;
            }
            int num4 = (int)Math.Ceiling((double)ef.Height);
            if (num4 > num8)
            {
                num4 = num8;
            }
            this.messageRectangle = new Rectangle(x, y, num3, num4);
        }

        protected override AccessibleObject CreateAccessibilityInstance()
        {
            if (this.DXAccessible == null)
            {
                return base.CreateAccessibilityInstance();
            }
            return this.DXAccessible.Accessible;
        }

        private void CreateButtons()
        {
            if ((this.Message.Buttons == null) || (this.Message.Buttons.Length <= 0))
            {
                throw new ArgumentException("At least one button must be specified", "buttons");
            }
            this.buttons = new SimpleButton[this.Message.Buttons.Length];
            int height = 0;
            for (int i = 0; i < this.buttons.Length; i++)
            {
                int index = (this.Message.DefaultButtonIndex + i) % this.buttons.Length;
                SimpleButton button = new SimpleButton();
                button.LookAndFeel.Assign(base.LookAndFeel);
                this.buttons[index] = button;
                button.DialogResult = this.Message.Buttons[index];
                if (button.DialogResult == DialogResult.None)
                {
                    throw new ArgumentException("The 'DialogResult.None' button cannot be specified", "buttons");
                }
                if (button.DialogResult == DialogResult.Cancel)
                {
                    base.CancelButton = button;
                }
                button.Text = this.GetButtonText(button.DialogResult);
                Size size = button.CalcBestSize();
                if (size.Width > button.Width)
                {
                    button.Width = size.Width;
                }
                if ((size.Height > height) && (size.Height > button.Height))
                {
                    height = size.Height;
                }
                base.Controls.Add(button);
            }
            if (height > 0)
            {
                foreach (SimpleButton button2 in this.buttons)
                {
                    button2.Height = height;
                }
            }
            if (this.buttons.Length == 1)
            {
                base.CancelButton = this.buttons[0];
            }
            if (base.CancelButton == null)
            {
                base.ControlBox = false;
            }
        }

        protected virtual DialogResult DoShowDialog(IWin32Window owner)
        {
            DialogResult result = base.ShowDialog(owner);
            base.Dispose();
            if (Array.IndexOf<DialogResult>(this.Message.Buttons, result) != -1)
            {
                return result;
            }
            return this.Message.Buttons[0];
        }

        private Size GetBordersSizes()
        {
            if (base.IsCustomPainter)
            {
                SkinPaddingEdges margins = base.FormPainter.Margins;
                return new Size(margins.Left + margins.Right, margins.Top + margins.Bottom);
            }
            return new Size(2 * SystemInformation.FixedFrameBorderSize.Width, (2 * SystemInformation.FixedFrameBorderSize.Height) + SystemInformation.CaptionHeight);
        }

        protected virtual string GetButtonText(DialogResult target)
        {
            switch (target)
            {
                case DialogResult.OK:
                    return Localizer.Active.GetLocalizedString(StringId.XtraMessageBoxOkButtonText);

                case DialogResult.Cancel:
                    return Localizer.Active.GetLocalizedString(StringId.XtraMessageBoxCancelButtonText);

                case DialogResult.Abort:
                    return Localizer.Active.GetLocalizedString(StringId.XtraMessageBoxAbortButtonText);

                case DialogResult.Retry:
                    return Localizer.Active.GetLocalizedString(StringId.XtraMessageBoxRetryButtonText);

                case DialogResult.Ignore:
                    return Localizer.Active.GetLocalizedString(StringId.XtraMessageBoxIgnoreButtonText);

                case DialogResult.Yes:
                    return Localizer.Active.GetLocalizedString(StringId.XtraMessageBoxYesButtonText);

                case DialogResult.No:
                    return Localizer.Active.GetLocalizedString(StringId.XtraMessageBoxNoButtonText);
            }
            return ('&' + target.ToString());
        }

        private Font GetCaptionFont()
        {
            if (base.IsCustomPainter)
            {
                return (Font)new AppearanceObject(base.FormPainter.GetDefaultAppearance()).Font.Clone();
            }
            return ControlUtils.GetCaptionFont();
        }

        private int GetCloseButtonWidth()
        {
            if (base.IsCustomPainter)
            {
                return new FormCaptionButtonSkinPainter(base.FormPainter).CalcObjectMinBounds(new FormCaptionButton(FormCaptionButtonKind.Close)).Width;
            }
            return SystemInformation.CaptionButtonSize.Width;
        }

        private AppearanceObject GetPaintAppearance()
        {
            return new AppearanceObject(base.Appearance, base.DefaultAppearance) { TextOptions = { WordWrap = WordWrap.Wrap, VAlignment = VertAlignment.Top, Trimming = Trimming.EllipsisCharacter } };
        }

        protected internal AccessibleObject GetParentAccessible()
        {
            return base.CreateAccessibilityInstance().Parent;
        }

        protected override void OnClosing(CancelEventArgs e)
        {
            if ((base.CancelButton == null) && (base.DialogResult == DialogResult.Cancel))
            {
                e.Cancel = true;
            }
            base.OnClosing(e);
        }

        protected override void OnKeyPress(KeyPressEventArgs e)
        {
            if (e.KeyChar == '\x0003')
            {
                e.Handled = true;
                Clipboard.SetDataObject(this.message.Caption + Environment.NewLine + Environment.NewLine + this.message.Text, true);
            }
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            using (GraphicsCache cache = new GraphicsCache(e))
            {
                if (this.Message.Icon != null)
                {
                    cache.Graphics.DrawIcon(this.Message.Icon, this.iconRectangle);
                }
                this.GetPaintAppearance().DrawString(cache, this.Message.Text, this.messageRectangle);
            }
        }

        protected override void OnVisibleChanged(EventArgs e)
        {
            base.OnVisibleChanged(e);
            if (base.Visible && !base.ContainsFocus)
            {
                base.Activate();
            }
        }

        private DialogResult ShowMessageBoxDialog()
        {
            if (this.Message.GetLookAndFeel() != null)
            {
                base.LookAndFeel.Assign(this.Message.GetLookAndFeel());
            }
            if (!this.AllowCustomLookAndFeel && (base.LookAndFeel.ActiveStyle != ActiveLookAndFeelStyle.Skin))
            {
                if (UserLookAndFeel.Default.ActiveStyle == ActiveLookAndFeelStyle.Office2003)
                {
                    base.LookAndFeel.SetStyle(LookAndFeelStyle.Office2003, true, false, "");
                }
                else
                {
                    base.LookAndFeel.SetDefaultStyle();
                }
            }
            this.Text = this.Message.Caption;
            base.FormBorderStyle = FormBorderStyle.FixedDialog;
            base.MinimizeBox = false;
            base.MaximizeBox = false;
            IWin32Window owner = this.Message.Owner;
            if (owner == null)
            {
                Form activeForm = Form.ActiveForm;
                if ((activeForm != null) && !activeForm.InvokeRequired)
                {
                    owner = activeForm;
                }
            }
            if (owner != null)
            {
                Control control = owner as Control;
                if (control != null)
                {
                    if (!control.Visible)
                    {
                        owner = null;
                    }
                    else
                    {
                        Form form2 = control.FindForm();
                        if ((form2 != null) && ((!form2.Visible || (form2.WindowState == FormWindowState.Minimized)) || ((form2.Right <= 0) || (form2.Bottom <= 0))))
                        {
                            owner = null;
                        }
                    }
                }
            }
            if (owner == null)
            {
                base.ShowInTaskbar = true;
                base.StartPosition = FormStartPosition.CenterScreen;
            }
            else
            {
                base.ShowInTaskbar = false;
                base.StartPosition = FormStartPosition.CenterParent;
            }
            this.CreateButtons();
            this.CalcIconBounds();
            this.CalcMessageBounds();
            this.CalcFinalSizes();
            Form form3 = owner as Form;
            if ((form3 != null) && form3.TopMost)
            {
                base.TopMost = true;
            }
            return this.DoShowDialog(owner);
        }

        public DialogResult ShowMessageBoxDialog(XtraMessageBoxArgs message)
        {
            this.message = message;
            return this.ShowMessageBoxDialog();
        }

        // Properties
        protected virtual bool AllowCustomLookAndFeel
        {
            get
            {
                return XtraMessageBox.AllowCustomLookAndFeel;
            }
        }

        protected override bool AllowSkinForEmptyText
        {
            get
            {
                return true;
            }
        }

        protected internal virtual BaseAccessible DXAccessible
        {
            get
            {
                if (this.dxAccessible == null)
                {
                    this.dxAccessible = new KNSMessageBoxAccessible(this);
                }
                return this.dxAccessible;
            }
        }

        public Rectangle IconRectangle
        {
            get
            {
                return this.iconRectangle;
            }
        }

        protected internal XtraMessageBoxArgs Message
        {
            get
            {
                return this.message;
            }
            set
            {
                this.message = value;
            }
        }

        public Rectangle MessageRectangle
        {
            get
            {
                return this.messageRectangle;
            }
        }

    }
}
